home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / xmsmgr.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-19  |  7.6 KB  |  281 lines

  1. #pragma inline
  2.  
  3. #include "xmsmgr.hpp"
  4.  
  5. xmsmgr::xmsmgr()
  6. {
  7.     xmsaddr = 0L;        // assume not present at first
  8.     installed = FALSE;
  9.     largest_free_xm = 0;
  10.     total_free_xm = 0;
  11.     errcode = 0;
  12.                 // this one is tricky
  13.                 // look at the pointer cast carefully
  14.  
  15.     list_handles = (unsigned (*)[128][2])new unsigned[128*2];
  16.     int i;
  17.     for (i = 0; i < 128; ++i)
  18.         (*list_handles)[i][0] = -1;
  19.     asm    {        // test for the HIMEM.SYS driver
  20.         mov ax,4300h    // 4300h = get install state
  21.         int 2fh        // call driver
  22.         cmp al,80h    // AL has 80h if present
  23.         je  is_installed
  24.         jmp not_installed
  25.     }
  26. is_installed:
  27.     long driver = xmsaddr;
  28.  
  29.     asm    {
  30.         mov ax,4310h        // request driver address
  31.         int 2fh            // call driver
  32.         mov word ptr driver,bx    // driver's far call address
  33.         mov word ptr driver+2,es
  34.     }
  35.     xmsaddr = driver;
  36.     installed = TRUE;
  37.     query_xms();
  38.     if (errcode)
  39.         installed = FALSE;
  40.     return;
  41.  
  42. not_installed:
  43.     installed = FALSE;
  44. }
  45.  
  46. xmsmgr::~xmsmgr()
  47. {
  48.     long driver = xmsaddr;
  49.     int i;
  50.     for (i = 0; i < 128; ++i)    {
  51.         unsigned emb = (*list_handles)[i][0];
  52.         if (emb != -1)    {    // if emb slot used
  53.             asm    {
  54.                 mov ah,0ah    // free emb
  55.                 mov dx,word ptr emb
  56.                 call dword ptr driver
  57.             }
  58.         }
  59.     }
  60.     delete list_handles;
  61. }
  62.  
  63. void xmsmgr::query_xms()
  64. {
  65.     long driver = xmsaddr;
  66.     unsigned x_largest = largest_free_xm;
  67.     unsigned x_total = total_free_xm;
  68.  
  69.     asm    {
  70.         mov ah,08h
  71.         call dword ptr driver
  72.         or ax,ax
  73.         jz badcall
  74.         mov word ptr x_largest,ax
  75.         mov word ptr x_total,dx
  76.     }
  77.     largest_free_xm = x_largest;
  78.     total_free_xm = x_total;
  79.     return;
  80. badcall:
  81.     errcode = _BL;        // store XMS error state
  82. }
  83.  
  84. char* xmsmgr::xmserr()
  85. {
  86.     static char errstring[80];
  87.  
  88.     strcpy (errstring, "XMS Memory error: ");
  89.     switch (errcode)    {
  90.         case notimpl:    strcat(errstring,"function not implemented.");
  91.                 break;
  92.         case vdisk:    strcat(errstring,"VDISK device driver present.");
  93.                 break;
  94.                 case a20err:    strcat(errstring,"A20 error.");
  95.                                 break;
  96.                 case generr:    strcat(errstring,"General driver error.");
  97.                                 break;
  98.                 case unrecov:   strcat(errstring,"Unrecoverable driver error.");
  99.                                 break;
  100.                 case nohma:     strcat(errstring,"HMA does not exist.");
  101.                                 break;
  102.                 case hmainuse:  strcat(errstring,"HMA is in use.");
  103.                                 break;
  104.                 case hmamin:    strcat(errstring,"Req. less than HMAMIN.");
  105.                                 break;
  106.                 case hmanotal:  strcat(errstring,"HMA is not allocated.");
  107.                                 break;
  108.                 case a20enab:   strcat(errstring,"A20 line still enabled.");
  109.                                 break;
  110.                 case allxms:    strcat(errstring,"All XM is allocated.");
  111.                                 break;
  112.                 case emmhandl:  strcat(errstring,"No more EMM handles.");
  113.                                 break;
  114.                 case invhandl:  strcat(errstring,"Invalid handle.");
  115.                                 break;
  116.                 case srchandl:  strcat(errstring,"Invalid source handle.");
  117.                                 break;
  118.                 case srcoffs:   strcat(errstring,"Invalid source offset.");
  119.                                 break;
  120.                 case dsthandl:  strcat(errstring,"Invalid destination handle.");
  121.                                 break;
  122.                 case dstoffs:   strcat(errstring,"Invalid destination offset.");
  123.                                 break;
  124.                 case invlen:    strcat(errstring,"Invalid length.");
  125.                                 break;
  126.                 case overlap:   strcat(errstring,"Blocks for move overlap.");
  127.                                 break;
  128.                 case parity:    strcat(errstring,"XMS parity error.");
  129.                                 break;
  130.                 case notlock:   strcat(errstring,"Block is not locked.");
  131.                                 break;
  132.                 case islock:    strcat(errstring,"Block is locked.");
  133.                                 break;
  134.                 case lockcnt:   strcat(errstring,"Exceeded max locks.");
  135.                                 break;
  136.                 case lockfail:  strcat(errstring,"Lock request failed.");
  137.                                 break;
  138.                 case smallumb:  strcat(errstring,"A smaller UMB is available.");
  139.                                 break;
  140.                 case noumb:     strcat(errstring,"No UMBs available.");
  141.                                 break;
  142.                 case umbseg:    strcat(errstring,"Invalid UMB segment number.");
  143.                                 break;
  144.                 case xmshandl:  strcat(errstring,"No more XMS handles.");
  145.                                 break;
  146.     }
  147.     return errstring;
  148. }
  149.  
  150. int xmsmgr::alloc_emb (size_t kbytes)
  151. {
  152.     int i;
  153.  
  154.     for (i = 0; i < 128; ++i)    {
  155.         if ((*list_handles)[i][0] == -1)    {    // unused slot
  156.             long driver = xmsaddr;
  157.             asm    {
  158.                 mov ah,09h        // request allocate
  159.                 mov dx,word ptr kbytes
  160.                 call dword ptr driver
  161.                 or ax,ax
  162.                 jz badnews
  163.                 jmp goodnews
  164.             }
  165. goodnews:
  166.             (*list_handles)[i][0] = _DX;    // save handle
  167.             (*list_handles)[i][1] = kbytes;
  168.             return i;    // return list element, not handle
  169. badnews:
  170.             errcode = _BL;        // save error code
  171.             installed = FALSE;    // and signal error
  172.             return -1;
  173.         }
  174.     }
  175.     // If you fall through, no more xms handles in list.
  176.  
  177.     errcode = xmshandl;
  178.     installed = FALSE;
  179.     return -1;
  180. }
  181.  
  182.  
  183. void xmsmgr::free_emb (int listnum)
  184. {
  185.     if (listnum >= 128 || (*list_handles)[listnum][0] == -1)
  186.         return;
  187.     unsigned handle = (*list_handles)[listnum][0];
  188.     long driver = xmsaddr;
  189.     asm    {
  190.         mov ah,0ah        // request deallocate
  191.         mov dx,word ptr handle
  192.         call dword ptr driver
  193.     }
  194. }
  195.  
  196. Boolean xmsmgr::stow (char far* send, size_t listnum,
  197.     unsigned long bytes, unsigned long ofs)
  198. {
  199.     if (listnum >= 128)    {
  200.         errcode = invhandl;
  201.         installed = FALSE;
  202.         return FALSE;
  203.     }
  204.  
  205.     xmsparms pstow;
  206.  
  207.     if (bytes % 2)
  208.         ++bytes;
  209.     pstow.emb_length = bytes;
  210.     pstow.source_handle = 0;
  211.     pstow.source_offset = (long)send;
  212.     pstow.dest_handle = (*list_handles)[listnum][0];
  213.     pstow.dest_offset = ofs;
  214.     long driver = xmsaddr;
  215.     asm    {
  216.         push ds            // be very careful with DS
  217.         push si
  218.         mov ah,0bh        // request EMB MOVE
  219.         lea si,pstow        // do SI first, about to lose DS
  220.         mov dx,ss
  221.         mov ds,dx
  222.         call dword ptr driver    // driver on stack, so it works
  223.         pop si            // be sure to recover these regs
  224.         pop dx
  225.         mov ds,dx
  226.         or ax,ax        // test the result
  227.         jz badnews
  228.         jmp goodnews
  229.     }
  230. goodnews:
  231.     return TRUE;
  232.  
  233. badnews:
  234.     errcode = _BL;        // save error code
  235.     installed = FALSE;    // and signal error
  236.     return FALSE;
  237. }
  238.  
  239. Boolean xmsmgr::fetch (char far* receive, size_t listnum,
  240.     unsigned long bytes, unsigned long ofs)
  241. {
  242.     if (listnum >= 128)    {
  243.         errcode = invhandl;
  244.         installed = FALSE;
  245.         return FALSE;
  246.     }
  247.  
  248.     xmsparms pfetch;
  249.  
  250.     if (bytes % 2)
  251.         ++bytes;
  252.     pfetch.emb_length = bytes;
  253.     pfetch.dest_handle = 0;
  254.     pfetch.dest_offset = (long)receive;
  255.     pfetch.source_handle = (*list_handles)[listnum][0];
  256.     pfetch.source_offset = ofs;
  257.     long driver = xmsaddr;
  258.     asm    {
  259.         push ds        // be very careful with DS
  260.         push si
  261.         mov ah,0bh    // request EMB MOVE
  262.         lea si,pfetch    // do SI first, about to lost DS
  263.         mov dx,ss
  264.         mov ds,dx
  265.         call dword ptr driver    // driver on stack, so it works
  266.         pop si        // be sure to recover these regs
  267.         pop dx
  268.         mov ds,dx
  269.         or ax,ax    // test the result
  270.         jz badnews
  271.         jmp goodnews
  272.     }
  273. goodnews:
  274.     return TRUE;
  275.  
  276. badnews:
  277.     errcode = _BL;        // save the error code
  278.     installed = FALSE;    // and signal error
  279.     return FALSE;
  280. }
  281.